/*
 * Copyright 2004-2005 公司名
 * 本软件及其所有拷贝的名称，与光盘上或本软件中注明的公司同在。
 * 本软件及文档享有版权，并受国家版权法及国际协约条款的保护。
 * 您不可以从本软件中去掉其版权声明；并保证为本软件的拷贝（本部或部分）* 复制版权声明。
 * 您同意制止以任何形式非法拷贝本软件及文档。
 * 版权信息参见：
 *      http://www.companyname.cn/licenses
 */

package com.companyname.common.util.mvc.config;

import java.io.*;

import java.util.*;

import org.jdom.*;

import org.jdom.output.*;

import org.jdom.input.*;

import org.apache.log4j.Logger;


import com.companyname.common.util.mvc.to.*;

/**
 * 描述： 读取配置文件（classes/mvc/moduleconfig.xml）
 *  1. getting service infos for c of mvc
 *  2. getting formbean infos for formbeanmaker
 *  3. getting validators bc infors for boolean caculator
 * author: amon_lei created in ：2005-4-6 22:03
 */

public class ModuleConfigReader extends ConfigReader
{
        static Logger logger = Logger.getLogger(ModuleConfigReader.class);

        private String moduleId;

        private Element root;

        public ModuleConfigReader(String moduleId)
          throws XmlFormatException
        {
                this.moduleId = moduleId;
                this.root = this.init(moduleId);
        }

        /**
         * 获取模块TO
         *      <mvc>
         *          <module id="" name="模块名">
         */
        public ModuleTO getModuleTO()
          throws XmlFormatException,NoSuchElementException
        {
                try
                {
                        logger.debug("查找<module id = '" + this.moduleId + "'>");
                        if(this.root.getChild("module").getAttributeValue("id").equals(moduleId))
                        {
                                return new ModuleTO(this.moduleId,
                                                    this.root.getChild("module").getAttributeValue("name")
                                                   );
                        }
                        else
                        {
                                throw new NoSuchElementException("查找<module id = '" + this.moduleId + "'>失败");
                        }
                }
                catch(Exception x)
                {
                        logger.error("获取moduleTO异常：" + x.toString());
                        throw new XmlFormatException(x.toString());
                }

        }

        /**
         * 获取实体TO
         *      <mvc>
         *          <module id="" name="模块名">
         *              <model id="" name="实体名">
         */
        public ModelTO getModelTO(String modelId)
          throws XmlFormatException,NoSuchElementException
        {
                try
                {
                        logger.debug("查找<model id = '" + modelId + "'>");
                        return new ModelTO(this.getModuleTO(),
                                           modelId,
                                           this.getElementByModelId(modelId).getAttributeValue("name")
                                           );
                }
                catch(NoSuchElementException nte)
                {
                        throw nte;
                }
                catch(Exception x)
                {
                        logger.error("获取modelTO异常：" + x.toString());
                        throw new XmlFormatException(x.toString());
                }

        }

        /**
         * 获取服务TO
         *      <mvc>
         *          <module id="" name="模块名">
         *              <model id="" name="实体名">
         *                  <services>
         *                      <service id="" name="服务名">
         *                          <class>XXX</class>
         */
        public ServiceTO getServiceTO(String modelId,
                                      String serviceId)
          throws XmlFormatException,NoSuchElementException
        {
                try
                {
                        logger.debug("查找<model id = '" + modelId + "'> " +
                                     "        <service id = '" + serviceId + "'> ");
                        Element serviceEle = this.getElementByModelIdNServiceId(modelId,serviceId);
                        // 采用spring new serviceInst,因此允许 mvc.dtd 中的service不用<class></class>
                        String classPath = null;
                        if(serviceEle.getChild("class") != null)
                        {
                                classPath = serviceEle.getChild("class").getText();
                        }
                        boolean logSwitch = true;
                        if(serviceEle.getAttributeValue("log") != null)
                        {
                                logSwitch = serviceEle.getAttributeValue("log").equals("true");
                        }
                        return new ServiceTO(this.getModuleTO(),
                                             this.getModelTO(modelId),
                                             serviceId,
                                             serviceEle.getAttributeValue("name"),
                                             classPath,
                                             logSwitch);
                }
                catch(NoSuchElementException nte)
                {
                        throw nte;
                }
                catch(Exception x)
                {
                        logger.error("获取ServiceTO异常：" + x.toString());
                        throw new XmlFormatException(x.toString());
                }
        }

        /**
         * 获取视图TO
         *      <mvc>
         *          <module id="" name="模块名">
         *              <model id="" name="实体名">
         *                  <services>
         *                      <service id="" name="服务名">
         *                          <class>XXX</class>
         *                          <views>
         *                              <successful></successful>
         *                              <failed></failed>
         *                          </views>
         */
        public ViewTO getViewTO(String modelId,
                                String serviceId,
                                String viewType)
          throws XmlFormatException
        {
                try
                {
                        Element viewEle = this.getElementByModelIdNServiceIdNViewType(modelId,serviceId,viewType);
                        boolean isForward = false;
                        if(viewEle.getAttributeValue("isforward") != null)
                        {
                                isForward = viewEle.getAttributeValue("isforward").equals("true");
                        }
                        return new ViewTO(this.getServiceTO(modelId,serviceId),
                                          viewEle.getText(),
                                          viewType,
                                          isForward);
                }
                catch(Exception x)
                {
                        logger.error("获取viewTO异常：" + x.toString());
                        throw new XmlFormatException(x.toString());
                }
        }

        /**
         * 获取model Element by modelId
         */
        public Element getElementByModelId(String modelId)
          throws NoSuchElementException
        {
                logger.debug("invoking getElementByModelId()");
                List modelEles = this.root.getChild("module").getChildren("model");
                Element ele = this.getElementByAttribute(modelEles,"id",modelId);
                if(ele != null)
                {
                        return ele;
                }
                else
                {
                        throw new NoSuchElementException("解析<model id = " + modelId + "> 失败");
                }


        }

        /**
         * 获取service Element By modelId And serviceId
         */
        public Element getElementByModelIdNServiceId(String modelId,
                                                     String serviceId)
          throws NoSuchElementException
        {
                logger.debug("invoking getElementByServiceId()");
                List serviceEles = this.getElementByModelId(modelId).getChild("services").getChildren("service");
                Element ele = this.getElementByAttribute(serviceEles,"id",serviceId);
                if(ele != null)
                {
                        return ele;
                }
                else
                {
                        throw new NoSuchElementException("解析<model id = " + modelId + "> " +
                                                         "       <services>" +
                                                         "           <service id = " + serviceId + "> 失败");
                }

        }

        /***
         * 获取View Element集合
         */
        public Element getElementByModelIdNServiceIdNViewType(String modelId,
                                                              String serviceId,
                                                              String viewType)
          throws NoSuchElementException
        {
                logger.debug("invoking getElementByModelIdNServiceIdNViewType()");
                Element viewEle = this.getElementByModelIdNServiceId(modelId,
                                                                     serviceId).getChild("views")
                                                                               .getChild(viewType);
                if( viewEle != null )
                {
                        return viewEle;
                }
                else
                {
                        throw new NoSuchElementException("解析<model id = " + modelId + "> " +
                                                        "       <services>" +
                                                        "           <service id = " + serviceId + "> " +
                                                        "               <views>" +
                                                        "                   <" + viewType + ">");
                }
        }

        /**
         * 获取formbeans in Validators configed
         */
        public List getFormBeansOfValidators(String modelId,
                                             String serviceId)
          throws NoSuchElementException
        {
                logger.debug("invoking getFormBeansOfValidators()");
                Element serviceEle = this.getElementByModelIdNServiceId(modelId,serviceId);
                logger.debug(" get module.model.service.validate.formbean" );
                return serviceEle.getChild("validate").getChildren("formbean");
        }

        /**
         * 获取formbean in Validators configed
         */
        public Element getFormBeanRefOfValidatorsByModelIdNFormBeanId(String modelId,
                                                                      String serviceId,
                                                                      String formBeanId)
          throws NoSuchElementException
        {
                logger.debug("invoking getFormBeanRefOfValidatorsByModelIdNFormBeanId()");
                return this.getElementByAttribute(this.getFormBeansOfValidators(modelId,serviceId),
                                                  "ref",
                                                  formBeanId
                                                 );
        }

        /**
         * 获取field　element by fieldId
         */
        public Element getFieldEleFromFormBeanByfieldId(String modelId,
                                                        String serviceId,
                                                        String formBeanId,
                                                        String fieldId)
          throws NoSuchElementException
        {
                logger.debug("invoking getFieldEleFromFormBeanByfieldId()");
                List fieldEles = this.getFormBeanRefOfValidatorsByModelIdNFormBeanId(modelId,serviceId,formBeanId).getChildren("field");
                return this.getElementByAttribute(fieldEles,"id",fieldId);
        }
        /**
         * 获取field　element by reqKey
         */
        public Element getFieldEleFromFormBeanByReqKey(String modelId,
                                                       String serviceId,
                                                       String formBeanId,
                                                       String reqKey)
          throws NoSuchElementException
        {
                logger.debug("invoking getFieldEleFromFormBeanByReqKey()");
                List fieldEles = this.getFormBeanRefOfValidatorsByModelIdNFormBeanId(modelId,serviceId,formBeanId).getChildren("field");
                return this.getElementByAttribute(fieldEles,"reqkey",reqKey);
        }

        /**
         * 获取formBean
         * 含有详细配置的部分如：class
         */
        public Element getFormBeanEle(String modelId,
                                      String formBeanId)
          throws NoSuchElementException
        {
                logger.debug("invoking getElementModelIdNFormBeanId()");
                List fbEles = this.getElementByModelId(modelId).getChildren("formbeans");
                Element fbEle = this.getElementByAttribute(fbEles,"id",formBeanId);
                return fbEle;
        }
}
